package com.unproy.model.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;


@Entity
@Table(name = "TBMEDI")
public class Media implements Serializable, Comparable<Media>, Publishable {
	private static final long	serialVersionUID	= -3425836221118360451L;
	private Long				mediaId;
	private MediaType			mediaType;
	private String				description;
	private User				createdBy;
	private Date				createdOn			= new Date();
	private Boolean				approved			= false;
	private User				approvedBy;
	private Date				approvedOn;
	private User				publishedBy;
	private Date				publishedOn;
	private String				sourceOwner;
	private Date				sourceDate;
	private String				mediaBigPath;
	private String				mediaArticlePath;
	private String				mediaListingPath;
	private String				mediaMobilePath;
	private Set<Tag>			tags				= new HashSet<Tag>();
	private List<Media>			relatedMedia		= new ArrayList<Media>();
	private Set<Article>		articles			= new HashSet<Article>();
	
	@Id
	@SequenceGenerator(name = "mediaId", sequenceName = "SQMEDI")
	@GeneratedValue(generator = "mediaId", strategy = GenerationType.SEQUENCE)
	@Column(name = "MEDIID", unique = true, nullable = false)
	public Long getMediaId() {
		return this.mediaId;
	}
	
	public void setMediaId(Long mediaId) {
		this.mediaId = mediaId;
	}
	
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "MTYPID", nullable = false)
	public MediaType getMediaType() {
		return this.mediaType;
	}
	
	public void setMediaType(MediaType mediaType) {
		this.mediaType = mediaType;
	}
	
	@Column(name = "DSCRPT", nullable = false)
	public String getDescription() {
		return this.description;
	}
	
	public void setDescription(String description) {
		this.description = description;
	}
	
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "CUSRID", nullable = false)
	@Override
	public User getCreatedBy() {
		return this.createdBy;
	}
	
	@Override
	public void setCreatedBy(User createdBy) {
		this.createdBy = createdBy;
	}
	
	@Column(name = "CRTDON", nullable = false)
	@Override
	public Date getCreatedOn() {
		return this.createdOn;
	}
	
	@Override
	public void setCreatedOn(Date createdOn) {
		this.createdOn = createdOn;
	}
	
	@Column(name = "ISAPRV", nullable = false)
	@Override
	public Boolean isApproved() {
		return this.approved;
	}
	
	@Override
	public void setApproved(Boolean approved) {
		this.approved = approved;
	}
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "AUSRID")
	@Override
	public User getApprovedBy() {
		return this.approvedBy;
	}
	
	@Override
	public void setApprovedBy(User approvedBy) {
		this.approvedBy = approvedBy;
	}
	
	@Column(name = "APRVON")
	@Override
	public Date getApprovedOn() {
		return this.approvedOn;
	}
	
	@Override
	public void setApprovedOn(Date approvedOn) {
		this.approvedOn = approvedOn;
	}
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "PUSRID")
	@Override
	public User getPublishedBy() {
		return this.publishedBy;
	}
	
	@Override
	public void setPublishedBy(User publisedBy) {
		this.publishedBy = publisedBy;
	}
	
	@Column(name = "PBSHON")
	@Override
	public Date getPublishedOn() {
		return this.publishedOn;
	}
	
	@Override
	public void setPublishedOn(Date publishedOn) {
		this.publishedOn = publishedOn;
	}
	
	@Column(name = "SRCOWN", nullable = false)
	public String getSourceOwner() {
		return this.sourceOwner;
	}
	
	public void setSourceOwner(String source) {
		this.sourceOwner = source;
	}
	
	@Column(name = "SRCDAT", nullable = false)
	public Date getSourceDate() {
		return this.sourceDate;
	}
	
	public void setSourceDate(Date takenOn) {
		this.sourceDate = takenOn;
	}
	
	@Column(name = "MEDBIG", nullable = false)
	public String getMediaBigPath() {
		return this.mediaBigPath;
	}
	
	public void setMediaBigPath(String thumbnailPath) {
		this.mediaBigPath = thumbnailPath;
	}
	
	@Column(name = "MEDART", nullable = false)
	public String getMediaArticlePath() {
		return this.mediaArticlePath;
	}
	
	public void setMediaArticlePath(String mediaArticlePath) {
		this.mediaArticlePath = mediaArticlePath;
	}
	
	@Column(name = "MEDLST", nullable = false)
	public String getMediaListingPath() {
		return this.mediaListingPath;
	}
	
	public void setMediaListingPath(String mediaListingPath) {
		this.mediaListingPath = mediaListingPath;
	}
	
	@Column(name = "MEDMOB", nullable = false)
	public String getMediaMobilePath() {
		return this.mediaMobilePath;
	}
	
	public void setMediaMobilePath(String mediaMobilePath) {
		this.mediaMobilePath = mediaMobilePath;
	}
	
	@ManyToMany(fetch = FetchType.EAGER)
	@JoinTable(name = "TBMDTG", joinColumns = @JoinColumn(name = "MEDIID", nullable = false), inverseJoinColumns = @JoinColumn(name = "TAGSID", nullable = false))
	public Set<Tag> getTags() {
		return this.tags;
	}
	
	public void setTags(Set<Tag> tags) {
		this.tags = tags;
	}
	
	@OneToMany(fetch = FetchType.EAGER)
	@JoinTable(name = "TBRLMD", joinColumns = @JoinColumn(name = "MEDIID", nullable = false), inverseJoinColumns = @JoinColumn(name = "RMEDID", nullable = false))
	public List<Media> getRelatedMedia() {
		return this.relatedMedia;
	}
	
	public void setRelatedMedia(List<Media> relatedMedia) {
		this.relatedMedia = relatedMedia;
	}
	
	@ManyToMany(fetch = FetchType.LAZY, mappedBy = "media")
	public Set<Article> getArticles() {
		return this.articles;
	}
	
	public void setArticles(Set<Article> articles) {
		this.articles = articles;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((this.createdBy == null) ? 0 : this.createdBy.hashCode());
		result = prime * result + ((this.createdOn == null) ? 0 : this.createdOn.hashCode());
		result = prime * result + ((this.mediaId == null) ? 0 : this.mediaId.hashCode());
		return result;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Media other = (Media) obj;
		if (this.createdBy == null) {
			if (other.createdBy != null)
				return false;
		} else if (!this.createdBy.equals(other.createdBy))
			return false;
		if (this.createdOn == null) {
			if (other.createdOn != null)
				return false;
		} else if (!this.createdOn.equals(other.createdOn))
			return false;
		if (this.mediaId == null) {
			if (other.mediaId != null)
				return false;
		} else if (!this.mediaId.equals(other.mediaId))
			return false;
		return true;
	}
	
	@Override
	public int compareTo(Media media) {
		return getCreatedOn().compareTo(media.getCreatedOn());
	}
	
	@Override
	public String toString() {
		return getDescription();
	}
}
